
/**
 * Clase que representa el problema de las garrafas
 *
 */
package Problemas;

import Busquedas.Estado;

public class Garrafas extends Problema {
	
	private short garrafa3;
	
	private short garrafa4;

	
	
	/**
	 * Constructor de la clase
	 */
	public Garrafas() {
		int []paramInicial = {3,4};
                int []paramObjetivo = {0,2};
                int []paramObjetivo1 = {1,2};
                int []paramObjetivo2 = {2,2};
                int []paramObjetivo3 = {3,2};
		Estado inicial = new Estado(paramInicial);
                Estado []objetivo = new Estado[4];
                objetivo[0]=new Estado(paramObjetivo);
                objetivo[1]=new Estado(paramObjetivo1);
                objetivo[2]=new Estado(paramObjetivo2);
                objetivo[3]=new Estado(paramObjetivo3);
                String [] nombresOperadores={"padre","llena3","llena4","vacia3","vacia4","vierte34","vierte43"};
		int [] costeOperadores={1,1,1,1,1,1};
		inicializa(inicial,objetivo,6,nombresOperadores,costeOperadores);
	}
	
	/**
	 * asigna los parametros del estado dado.
	 * @param e estado dado.
	 */
	public void asignaParametros(Estado e){
		garrafa3 = (short)e.getParametro(0);
		garrafa4 = (short)e.getParametro(1);
	}
	
	
	
	/**
	 * llena la garrafa de tres
	 * @return nuevo estado.
	 */
	public Estado llena3(){
		if (garrafa3 < 3 ){
			int[] paramNuevos = {3,garrafa4}; 
			return new Estado(paramNuevos);
		}
		return null;
	}
	
	
	/**
	 * llena la garrafa de cuatro
	 * @return nuevo estado.
	 */
	public Estado llena4(){
		if (garrafa4 < 4){
			int[] paramNuevos = {garrafa3,4}; 
			return new Estado(paramNuevos);
		}
		return null;
	}
	
	
	/**
	 * vacia la garrafa de tres
	 * @return nuevo estado.
	 */
	public Estado vacia3(){
		if (garrafa3 > 0){
			int[] paramNuevos = {0,garrafa4}; 
			return new Estado(paramNuevos);
		}
		return null;
	}
	
	
	/**
	 * vacia la garrafa de cuatro
	 * @return nuevo estado.
	 */
	public Estado vacia4(){
		if (garrafa4 > 0){
			int[] paramNuevos = {garrafa3,0}; 
			return new Estado(paramNuevos);
		}
		return null;
	}
	

	/**
	 * vierte la garrafa de tres en la de cuatro
	 * @return nuevo estado.
	 */
	public Estado vierte34(){
		if (garrafa3 > 0 && garrafa4 < 4){
			int n4 = Math.min(4,garrafa3+garrafa4);
			int n3 = garrafa3-(n4-garrafa4);
			int[] paramNuevos = {n3,n4};
			return new Estado(paramNuevos);
		}
		return null;
	}

	
	/**
	 * vierte la garrafa de cuatro en la de tres
	 * @return nuevo estado.
	 */
	public Estado vierte43(){
		if (garrafa4 > 0 && garrafa3 < 3){
			int n3 = Math.min(3,garrafa3+garrafa4);
			int n4 = garrafa4-(n3-garrafa3);
			int[] paramNuevos = {n3,n4};
			return new Estado(paramNuevos);
		}
		return null;
	}
	
	
	
	/* (non-Javadoc)
	 * @see Problema#getOperadorInverso(int)
	 */
	public int getOperadorInverso(int op){
		int inverso = op;
		switch(op){
		case 0:
			inverso = 2;
			break;
		case 1:
			inverso = 3;
			break;
		case 2:
			inverso = 0;
			break;
		case 3:
			inverso = 1;
		case 4:
			inverso = -1;
			break;
		case 5:
			inverso = -1;
			break;
		}
		return inverso;
	}
	
	
	
	/* (non-Javadoc)
	 * @see Problema#aplicaOperador(Estado, int)
	 */
	public Estado aplicaOperador(Estado actual, int i){
		asignaParametros(actual);
		Estado siguiente = null;
		switch(i){
		case 0:
			siguiente = llena3();
			break;
		case 1:
			siguiente = llena4();
			break;
		case 2:
			siguiente = vacia3();
			break;
		case 3:
			siguiente = vacia4();
			break;
		case 4:
			siguiente = vierte34();
			break;
		case 5:
			siguiente = vierte43();
		}
		return siguiente;	
	}
 public int funcionHeuristica(Estado estado){
       asignaParametros(estado);
		return (Math.abs(garrafa4-2));
	}

}
